package ua.kpi.oblamskyiv.parser;

import ua.kpi.oblamskyiv.io.exception.IllegalAnswerFormatException;
import ua.kpi.oblamskyiv.io.exception.IllegalAnswerIndexException;
import ua.kpi.oblamskyiv.testcase.Answers;
import ua.kpi.oblamskyiv.testcase.answer.Answer;
import ua.kpi.oblamskyiv.testcase.question.AlternativesQuestion;
import ua.kpi.oblamskyiv.testcase.question.Question;

import java.util.ArrayList;
import java.util.List;

public class IndexAnswersParser implements AnswersParser {
    private static final String COMMA_WITH_OPTIONAL_SPACE = ",(\\s)*";

    @Override
    public Answers parse(Question question, String rawString)
            throws IllegalAnswerFormatException {
        assert(question instanceof AlternativesQuestion);

        AlternativesQuestion altQuestion = (AlternativesQuestion) question;
        List<Answer> answersByNumbers = new ArrayList<Answer>();

        for (int index : parseAnswersIndexes(rawString)) {
            /*
             *  To get corresponding answer from list we must use (index - 1),
             *  'cause user question numeration starts from 1 (not 0!)
             */
            try {
                String text = altQuestion.getAlternativeText(index - 1);
                answersByNumbers.add(new Answer(text));
            } catch (IndexOutOfBoundsException e) {
                throw new IllegalAnswerIndexException();
            }
        }
        return new Answers(answersByNumbers);
    }

    protected int[] parseAnswersIndexes(String rawString)
            throws IllegalAnswerFormatException {
        String[] answerStrings = rawString.split(COMMA_WITH_OPTIONAL_SPACE);

        int[] answerNumbers = new int[answerStrings.length];

        for (int index = 0; index < answerNumbers.length; index++) {
            try {
                answerNumbers[index] = Integer.parseInt(answerStrings[index]);
            } catch (NumberFormatException e) {
                throw new IllegalAnswerFormatException();
            }
        }
        return answerNumbers;
    }
}
